package com.niuwa.p2p.service.impl.yeepay;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.bind.JAXB;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.niuwa.p2p.core.constant.YeePayBizTypeEnum;
import com.niuwa.p2p.core.constant.YeePayBussinesEnum;
import com.niuwa.p2p.core.constant.YeePayClassTypeEnum;
import com.niuwa.p2p.core.constant.YeePayServiceEnum;
import com.niuwa.p2p.core.constant.YeePaySubjoinEnum;
import com.niuwa.p2p.core.utils.UUIDUtil;
import com.niuwa.p2p.core.utils.yeepay.SignUtil;
import com.niuwa.p2p.entity.yeepay.TenderExtend;
import com.niuwa.p2p.entity.yeepay.TenderProperty;
import com.niuwa.p2p.entity.yeepay.YeePayBaseResponse;
import com.niuwa.p2p.entity.yeepay.YeePayLogInfo;
import com.niuwa.p2p.entity.yeepay.YeePayMessage;
import com.niuwa.p2p.entity.yeepay.YeePayMongoInfo;
import com.niuwa.p2p.entity.yeepay.cp.CpExtendRequest;
import com.niuwa.p2p.entity.yeepay.mobile.YeePayAppRechargeRequest;
import com.niuwa.p2p.entity.yeepay.mobile.YeePayAppRegisterRequest;
import com.niuwa.p2p.entity.yeepay.mobile.YeePayAppWithdrawRequest;
import com.niuwa.p2p.entity.yeepay.mobile.YeepayCpAppTenderRequest;
import com.niuwa.p2p.entity.yeepay.mobile.YeepayCpAppTransferRequest;
import com.niuwa.p2p.service.yeepay.YeePayAppService;
import com.niuwa.p2p.service.yeepay.YeePayLogService;
import com.niuwa.p2p.service.yeepay.YeePayMongoService;

/**
 * 
 * @title 易宝支付调用服务
 *
 * @author tennyqin
 * @version 1.0
 * @created 2015年4月14日
 */
@Service
public class YeePayAppServiceImpl implements YeePayAppService {

	@Value("#{propertiesReader['yeepay.pfx.path']}")
	private String pfx;

	@Value("#{propertiesReader['yeepay.app.host']}")
	private String host;

	@Value("#{propertiesReader['yeepay.user.platformNo']}")
	private String platformNo;

	@Value("#{propertiesReader['yeepay.service.notifyUrl']}")
	private String notifyUrl;

	@Value("#{propertiesReader['yeepay.app.callBackUrl']}")
	private String callbackUrl;

	@Autowired
	private YeePayLogService yeePayLogService;

//	@Autowired
	private YeePayMongoService yeePayMongoService;

	private static Logger logger = Logger.getLogger(YeePayAppServiceImpl.class); // 日志记录

	@Override
	public YeePayBaseResponse doRegister(YeePayAppRegisterRequest request) {
		request.setRequestNo(String.valueOf(UUIDUtil.getBigIntegerUUid()));
		request.setPlatformNo(platformNo);
		request.setNotifyUrl(notifyUrl);
		request.setCallbackUrl(callbackUrl);
		return doSignNet(request, host + "/toRegister", null,
				request.getRequestNo(), request.getPlatformUserNo());
	}

	@Override
	public YeePayBaseResponse doRecharge(YeePayAppRechargeRequest request) {
		request.setRequestNo(String.valueOf(UUIDUtil.getBigIntegerUUid()));
		request.setPlatformNo(platformNo);
		request.setNotifyUrl(notifyUrl);
		request.setCallbackUrl(callbackUrl);
		return doSignNet(request, host + "/toRecharge", null,
				request.getRequestNo(), request.getPlatformUserNo());
	}

	@Override
	public YeePayBaseResponse DoWithdraw(YeePayAppWithdrawRequest request) {
		request.setRequestNo(String.valueOf(UUIDUtil.getBigIntegerUUid()));
		request.setPlatformNo(platformNo);
		request.setNotifyUrl(notifyUrl);
		request.setCallbackUrl(callbackUrl);
		return doSignNet(request, host + "/toWithdraw", null,
				request.getRequestNo(), request.getPlatformUserNo());
	}

	// 转账
	@Override
	public YeePayBaseResponse doTransfer(YeepayCpAppTransferRequest request) {
		request.setRequestNo(String.valueOf(UUIDUtil.getBigIntegerUUid()));
		request.setPlatformNo(platformNo);
		request.setNotifyUrl(notifyUrl);
		request.setUserType("MEMBER");
		request.setCallbackUrl(callbackUrl);
		return doSignNet(request, host + "/toCpTransaction", null,
				request.getRequestNo(), request.getPlatformUserNo());
	}

	// 投标 、还款、债权转让 [注意类型不一样参数对应不一样]
	@Override
	public YeePayBaseResponse doCpTransaction(YeepayCpAppTenderRequest request,
			CpExtendRequest cPrequest) {
		request.setRequestNo(String.valueOf(UUIDUtil.getBigIntegerUUid()));
		request.setPlatformNo(platformNo);
		request.setNotifyUrl(notifyUrl);
		request.setUserType("MEMBER");
		request.setCallbackUrl(callbackUrl);
		List<TenderProperty> properts = new ArrayList<TenderProperty>();
		TenderExtend tenderExtend = new TenderExtend();
		if (request.getBizType() == YeePayBizTypeEnum.TENDER) { // 投标

			TenderProperty propertNo = new TenderProperty();
			propertNo.setName("tenderOrderNo");
			propertNo.setValue(cPrequest.getTenderEntity().getTenderOrderNo());
			properts.add(propertNo);

			TenderProperty propertName = new TenderProperty();
			propertName.setName("tenderName");
			propertName.setValue(cPrequest.getTenderEntity().getTenderName());
			properts.add(propertName);

			TenderProperty propertAmount = new TenderProperty();
			propertAmount.setName("tenderAmount");
			propertAmount.setValue(cPrequest.getTenderEntity()
					.getTenderAmount());
			properts.add(propertAmount);

			TenderProperty propertDescription = new TenderProperty();
			propertDescription.setName("tenderDescription");
			propertDescription.setValue(cPrequest.getTenderEntity()
					.getTenderDescription());
			properts.add(propertDescription);

			TenderProperty propertPlat = new TenderProperty();
			propertPlat.setName("borrowerPlatformUserNo");
			propertPlat.setValue(cPrequest.getTenderEntity()
					.getBorrowerPlatformUserNo());
			properts.add(propertPlat);

			tenderExtend.setProperty(properts);
			request.setExtend(tenderExtend);
		}
		if (request.getBizType() == YeePayBizTypeEnum.REPAYMENT) { // 还款
			TenderProperty propertNo = new TenderProperty();
			propertNo.setName("tenderOrderNo ");
			propertNo.setValue(cPrequest.getRepaymentEntity()
					.getTenderOrderNo());
			properts.add(propertNo);
			tenderExtend.setProperty(properts);
			request.setExtend(tenderExtend);
		}
		if (request.getBizType() == YeePayBizTypeEnum.CREDIT_ASSIGNMENT) { // 债权转让
			TenderProperty propertNo = new TenderProperty();
			propertNo.setName("tenderOrderNo ");
			propertNo.setValue(cPrequest.getCreditAssignment()
					.getTenderOrderNo());
			properts.add(propertNo);

			TenderProperty propertPlat = new TenderProperty();
			propertPlat.setName("creditorPlatformUserNo ");
			propertPlat.setValue(cPrequest.getCreditAssignment()
					.getCreditorPlatformUserNo());
			properts.add(propertPlat);

			TenderProperty propertReq = new TenderProperty();
			propertReq.setName("originalRequestNo ");
			propertReq.setValue(cPrequest.getCreditAssignment()
					.getOriginalRequestNo());
			properts.add(propertReq);

			tenderExtend.setProperty(properts);
			request.setExtend(tenderExtend);
		}
		return doSignNet(request, host + "/toCpTransaction", null,
				request.getRequestNo(), request.getPlatformUserNo(), cPrequest);
	}

	// 网关连接
	private YeePayBaseResponse doSignNet(Object obj, String url,
			String service, String requestNo, String platformUserNo) {
		YeePayBaseResponse response = new YeePayBaseResponse();
		try {
			StringWriter w = new StringWriter();
			JAXB.marshal(obj, w);
			String s = w.toString();
			s = s.replaceAll("[\\r\\n]", "");
			StringBuffer params = new StringBuffer();
			params.append("req=" + s);
			params.append("&service=" + service);
			params.append("&sign=" + "r7B");
			response.setUrl(url);
			response.setMessage(params.toString());
			YeePayMessage yeePayMessage = writeLogger(response, obj);
			yeePayMessage.setRquestNo(requestNo);
			yeePayMessage.setPlatformUserNo(platformUserNo);
			insertDBLogger(yeePayMessage);
			inserMongoDBKey(yeePayMessage, SignUtil.sign(s, pfx, "123qwe"));
		} catch (Exception ex) {
			logger.error("执行签名操作失败!!", ex);
		}
		return response;
	}

	// 网关连接 [投标，还款，债权转让]
	private YeePayBaseResponse doSignNet(Object obj, String url,
			String service, String requestNo, String platformUserNo,
			CpExtendRequest cPrequest) {
		YeePayBaseResponse response = new YeePayBaseResponse();
		try {
			StringWriter w = new StringWriter();
			JAXB.marshal(obj, w);
			String s = w.toString();
			s = s.replaceAll("[\\r\\n]", "");
			StringBuffer params = new StringBuffer();
			params.append("req=" + s);
			params.append("&service=" + service);
			params.append("&sign=" + "r7B");
			response.setUrl(url);
			response.setMessage(params.toString());
			YeePayMessage yeePayMessage = writeLogger(response, cPrequest);
			yeePayMessage.setRquestNo(requestNo);
			yeePayMessage.setPlatformUserNo(platformUserNo);
			insertDBLogger(yeePayMessage);
			inserMongoDBKey(yeePayMessage, SignUtil.sign(s, pfx, "123qwe"));
		} catch (Exception ex) {
			logger.error("执行签名操作失败!!", ex);
		}
		return response;
	}

	/**
	 * 写入网关日志
	 * 
	 * @param response
	 * @param obj
	 * @return
	 */
	private YeePayMessage writeLogger(YeePayBaseResponse response, Object obj) {
		String className = obj.getClass().getSimpleName();
		StringBuffer buffer = new StringBuffer();
		YeePayMessage yeePayMessage = new YeePayMessage();
		if (className.equals(YeePayClassTypeEnum.YeePayAppRegisterRequest
				.toString())) {
			buffer.append("执行app注册用户操作请求;请求参数报文：" + response.getMessage());
			yeePayMessage.setOperateDescription("执行app注册用户操作请求");
			yeePayMessage.setYeePaySubjoinEnum(YeePaySubjoinEnum.ACCOUNT_INFO);
			yeePayMessage.setYeePayServiceEnum(YeePayServiceEnum.REGISTER);
			yeePayMessage
					.setYeePayBussinesEnum(YeePayBussinesEnum.PERSONREGISTER);
		}
		if (className.equals(YeePayClassTypeEnum.YeePayAppRechargeRequest
				.toString())) {
			buffer.append("执行app充值操作请求;请求参数报文：" + response.getMessage());
			yeePayMessage.setOperateDescription("执行app充值操作请求");
			yeePayMessage.setYeePaySubjoinEnum(YeePaySubjoinEnum.QUERY);
			yeePayMessage.setYeePayServiceEnum(YeePayServiceEnum.RECHARGE);
		}
		if (className.equals(YeePayClassTypeEnum.YeePayAppWithdrawRequest
				.toString())) {
			buffer.append("执行app提现操作请求;请求参数报文：" + response.getMessage());
			yeePayMessage.setOperateDescription("执行app提现操作请求");
			yeePayMessage.setYeePaySubjoinEnum(YeePaySubjoinEnum.QUERY);
			yeePayMessage.setYeePayServiceEnum(YeePayServiceEnum.WITHDRAW);
		}
		if (className.equals(YeePayClassTypeEnum.YeepayCpAppTransferRequest
				.toString())) {
			buffer.append("执行app转账操作请求;请求参数报文：" + response.getMessage());
			yeePayMessage.setOperateDescription("执行app转账操作请求");
			yeePayMessage.setYeePaySubjoinEnum(YeePaySubjoinEnum.QUERY);
			yeePayMessage.setYeePayServiceEnum(YeePayServiceEnum.TRANSACTION);
			yeePayMessage.setYeePayBussinesEnum(YeePayBussinesEnum.TRANSACTION);
		}
		if (className
				.equals(YeePayClassTypeEnum.YeePayEnterpriseRegisterRequest
						.toString())) {
			buffer.append("执行app企业用户注册操作请求;请求参数报文：" + response.getMessage());
			yeePayMessage.setOperateDescription("执行app企业用户注册操作请求");
			yeePayMessage.setYeePaySubjoinEnum(YeePaySubjoinEnum.ACCOUNT_INFO);
			yeePayMessage.setYeePayServiceEnum(YeePayServiceEnum.REGISTER);
			yeePayMessage
					.setYeePayBussinesEnum(YeePayBussinesEnum.ENTERREGISTER);
		}
		logger.error(buffer.toString());
		yeePayMessage.setMessage(buffer.toString());
		return yeePayMessage;
	}

	/**
	 * 写入网关日志
	 * 
	 * @param response
	 * @param obj
	 * @return
	 */
	private YeePayMessage writeLogger(YeePayBaseResponse response,
			CpExtendRequest cPrequest) {
		StringBuffer buffer = new StringBuffer();
		YeePayMessage yeePayMessage = new YeePayMessage();
		if (null != cPrequest.getTenderEntity().getTenderOrderNo()) {
			buffer.append("执行app投标操作请求;请求参数报文：" + response.getMessage());
			yeePayMessage.setOperateDescription("执行app投标操作请求");
		}
		if (null != cPrequest.getRepaymentEntity().getTenderOrderNo()) {
			buffer.append("执行app还款操作请求;请求参数报文：" + response.getMessage());
			yeePayMessage.setOperateDescription("执行app还款操作请求");
		}
		if (null != cPrequest.getCreditAssignment().getTenderOrderNo()) {
			buffer.append("执行app债权转让操作请求;请求参数报文：" + response.getMessage());
			yeePayMessage.setOperateDescription("执行app债权转让操作请求");
		}
		yeePayMessage.setYeePayServiceEnum(YeePayServiceEnum.TRANSACTION);
		yeePayMessage.setYeePaySubjoinEnum(YeePaySubjoinEnum.QUERY);
		yeePayMessage.setYeePayBussinesEnum(YeePayBussinesEnum.TRANSACTION);
		logger.error(buffer.toString());
		yeePayMessage.setMessage(buffer.toString());
		return yeePayMessage;
	}

	/**
	 * 日志入库
	 * 
	 * @param yeePayMessage
	 */
	private void insertDBLogger(YeePayMessage yeePayMessage) {
		if (null == yeePayMessage.getMessage()
				|| null == yeePayMessage.getOperateDescription()) {
			logger.error("易宝日志记录入参不能为空");
			return;
		}
		if (null == yeePayMessage.getRquestNo()
				|| null == yeePayMessage.getPlatformUserNo()) {
			logger.error("易宝日志记录入参不能为空");
			return;
		}
		YeePayLogInfo yeePayLogInfo = new YeePayLogInfo();
		yeePayLogInfo.setOperateDescription(yeePayMessage
				.getOperateDescription());
		yeePayLogInfo.setRequestMessage(yeePayMessage.getMessage());
		yeePayLogInfo.setRquestNo(yeePayMessage.getRquestNo());
		yeePayLogInfo.setPlatformUserNo(yeePayMessage.getPlatformUserNo());
		yeePayLogInfo.setCreated(new Date());
		yeePayLogInfo.setDispose(0);//默认未处理
		yeePayLogService.saveLog(yeePayLogInfo);
	}

	/**
	 * 进入mongoDb队列 [补单机制准备]
	 */
	public void inserMongoDBKey(YeePayMessage yeePayMessage, String sign) {
		if (null == yeePayMessage.getRquestNo()
				|| null == yeePayMessage.getPlatformUserNo()) {
			logger.error("易宝mongoDb入参不能为空");
			return;
		}
		YeePayMongoInfo yeePayMongoInfo = new YeePayMongoInfo();
		yeePayMongoInfo.setRequestNo(yeePayMessage.getRquestNo());
		yeePayMongoInfo.setRequestMessage(yeePayMessage.getMessage());
		yeePayMongoInfo.setSign(sign);
		yeePayMongoInfo.setYeePaySubjoinEnum(yeePayMessage
				.getYeePaySubjoinEnum());
		yeePayMongoInfo.setPlatformUserNo(yeePayMessage.getPlatformUserNo());
		yeePayMongoInfo.setYeePayServiceEnum(yeePayMessage
				.getYeePayServiceEnum());
		yeePayMongoService.save(yeePayMongoInfo);
	}
}
